<template>
  <div ref="editorRef" class="monaco-editor"></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as monaco from 'monaco-editor'

const props = defineProps({
  value: {
    type: String,
    default: ''
  },
  language: {
    type: String,
    default: 'javascript'
  },
  theme: {
    type: String,
    default: 'vs-dark'
  },
  options: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits(['update:value', 'change'])

const editorRef = ref(null)
let editor = null

// 创建编辑器
const createEditor = () => {
  try {
    if (!editorRef.value) return

    // 销毁已存在的编辑器实例
    if (editor) {
      editor.dispose()
    }

    // 创建新的编辑器实例
    editor = monaco.editor.create(editorRef.value, {
      value: props.value,
      language: props.language,
      theme: props.theme,
      automaticLayout: true,
      scrollBeyondLastLine: false,
      minimap: { enabled: false },
      fontSize: 14,
      tabSize: 2,
      ...props.options
    })

    // 监听内容变化
    editor.onDidChangeModelContent(() => {
      const value = editor.getValue()
      emit('update:value', value)
      emit('change', value)
    })
  } catch (error) {
    console.error('创建编辑器失败:', error)
  }
}

// 更新编辑器内容
const updateContent = (value) => {
  try {
    if (editor && value !== editor.getValue()) {
      editor.setValue(value)
    }
  } catch (error) {
    console.error('更新内容失败:', error)
  }
}

// 更新编辑器语言
const updateLanguage = (language) => {
  try {
    if (editor) {
      monaco.editor.setModelLanguage(editor.getModel(), language)
    }
  } catch (error) {
    console.error('更新语言失败:', error)
  }
}

// 更新编辑器主题
const updateTheme = (theme) => {
  try {
    if (editor) {
      monaco.editor.setTheme(theme)
    }
  } catch (error) {
    console.error('更新主题失败:', error)
  }
}

// 监听属性变化
watch(() => props.value, updateContent)
watch(() => props.language, updateLanguage)
watch(() => props.theme, updateTheme)

onMounted(() => {
  // 延迟创建编辑器,确保DOM已经渲染
  setTimeout(() => {
    createEditor()
  }, 0)
})

onBeforeUnmount(() => {
  if (editor) {
    editor.dispose()
  }
})
</script>

<style scoped>
.monaco-editor {
  width: 100%;
  height: 100%;
}
</style> 